package com.ms3ds.deviceData.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

import com.ms3ds.deviceData.api.domain.Device;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ms3ds.deviceData.mapper.SensorDataMapper;
import com.ms3ds.deviceData.domain.SensorData;

import com.ms3ds.deviceData.domain.Sensor;
import com.ms3ds.deviceData.domain.vo.SensorDataVO;
import com.ms3ds.deviceData.domain.vo.WaterPumpDataVO;
import com.ms3ds.deviceData.domain.vo.AreaSensorDataVO;
import com.ms3ds.deviceData.domain.vo.BatteryDataVO;
import com.ms3ds.deviceData.service.ISensorDataService;
import com.ms3ds.deviceData.service.IDeviceService;
import com.ms3ds.deviceData.service.ISensorService;
import com.ms3ds.deviceData.service.IMiningRecordService;
import com.ms3ds.common.core.domain.R;
import com.ms3ds.mineInfo.api.RemoteAreaService;
import com.ms3ds.mineInfo.api.RemoteMineService;
import com.ms3ds.mineInfo.api.domain.Area;
import com.ms3ds.mineInfo.api.domain.Mine;

/**
 * 传感器数据Service业务层处理
 * 
 * @author zlw
 * @date 2025-09-21
 */
@Service
public class SensorDataServiceImpl implements ISensorDataService 
{
    @Autowired
    private SensorDataMapper sensorDataMapper;
    
    @Autowired
    private IDeviceService deviceService;
    
    @Autowired
    private ISensorService sensorService;

    @Autowired
    private RemoteAreaService remoteAreaService;

    @Autowired
    private IMiningRecordService miningRecordService;
    
    @Autowired
    private RemoteMineService remoteMineService;

    /**
     * 查询传感器数据
     * 
     * @param id 传感器数据主键
     * @return 传感器数据
     */
    @Override
    public SensorData selectSensorDataById(Long id)
    {
        return sensorDataMapper.selectSensorDataById(id);
    }

    /**
     * 查询传感器数据列表
     * 
     * @param sensorData 传感器数据
     * @return 传感器数据
     */
    @Override
    public List<SensorData> selectSensorDataList(SensorData sensorData)
    {
        return sensorDataMapper.selectSensorDataList(sensorData);
    }

    /**
     * 查询传感器数据列表(包含传感器名称和设备名称)
     * 
     * @param sensorData 传感器数据查询条件
     * @return 传感器数据VO集合
     */
    @Override
    public List<SensorDataVO> selectSensorDataVOList(SensorData sensorData)
    {
        return sensorDataMapper.selectSensorDataVOList(sensorData);
    }

    /**
     * 新增传感器数据
     * 
     * @param sensorData 传感器数据
     * @return 结果
     */
    @Override
    public int insertSensorData(SensorData sensorData)
    {
        return sensorDataMapper.insertSensorData(sensorData);
    }

    /**
     * 修改传感器数据
     * 
     * @param sensorData 传感器数据
     * @return 结果
     */
    @Override
    public int updateSensorData(SensorData sensorData)
    {
        return sensorDataMapper.updateSensorData(sensorData);
    }

    /**
     * 批量删除传感器数据
     * 
     * @param ids 需要删除的传感器数据主键
     * @return 结果
     */
    @Override
    public int deleteSensorDataByIds(Long[] ids)
    {
        return sensorDataMapper.deleteSensorDataByIds(ids);
    }

    /**
     * 删除传感器数据信息
     * 
     * @param id 传感器数据主键
     * @return 结果
     */
    @Override
    public int deleteSensorDataById(Long id)
    {
        return sensorDataMapper.deleteSensorDataById(id);
    }

    /**
     * 动态为所有区域的所有传感器生成当天假数据
     * 按照 区域 -> 设备 -> 传感器 -> 传感器数据 的层次结构
     * 
     * @return 结果
     */
    @Override
    public R<Boolean> generateTodayFakeData()
    {
        try {
            List<SensorData> sensorDataList = new ArrayList<>();
            Date currentTime = new Date();
            Random random = new Random();
            
            // 1. 获取所有矿山信息
            R<List<Mine>> remoteMineList = remoteMineService.getAllForRemote();
            if (remoteMineList == null || remoteMineList.getData() == null || remoteMineList.getData().isEmpty()) {
                return R.ok(false);
            }
            
            List<Mine> mines = remoteMineList.getData();
            
            // 2. 遍历每个矿山
            for (Mine mine : mines) {
                // 3. 获取该矿山的工作区域信息
                R<List<Area>> areaListForRemote = remoteAreaService.getAreaListByMineIdForRemote(mine.getId());
                List<Area> areas = new ArrayList<>();
                if (areaListForRemote == null || areaListForRemote.getData() == null || areaListForRemote.getData().isEmpty()) {
                    continue; // 跳过没有区域的矿山
                } else {
                    areas = areaListForRemote.getData();
                }
                
                // 4. 遍历每个区域
                for (Area area : areas) {
                    // 5. 查询该区域下的所有设备
                    Device deviceQuery = new Device();
                    deviceQuery.setAreaId(area.getId());
                    List<Device> devices = deviceService.selectDeviceList(deviceQuery);
                    
                    if (devices != null && !devices.isEmpty()) {
                        // 6. 遍历每个设备
                        for (Device device : devices) {
                            // 7. 查询该设备下的所有传感器
                            Sensor sensorQuery = new Sensor();
                            sensorQuery.setDeviceId(device.getId());
                            List<Sensor> sensors = sensorService.selectSensorList(sensorQuery);
                            
                            if (sensors != null && !sensors.isEmpty()) {
                                // 8. 为每个在线传感器生成假数据
                                for (Sensor sensor : sensors) {
                                    // 只有在线的传感器(status=1)才生成数据
                                    if (sensor.getStatus() != null && sensor.getStatus() == 1) {
                                        SensorData sensorData = generateSensorDataBySensor(sensor, currentTime, random);
                                        if (sensorData != null) {
                                            sensorDataList.add(sensorData);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            
            // 9. 批量插入生成的数据
            int result = insertSensorDataBatch(sensorDataList);
            return R.ok(result > 0);
            
        } catch (Exception e) {
            return R.fail("生成传感器数据失败：" + e.getMessage());
        }
    }
    
    /**
     * 根据传感器信息生成对应的假数据
     * 
     * @param sensor 传感器信息
     * @param currentTime 当前时间
     * @param random 随机数生成器
     * @return 传感器数据
     */
    private SensorData generateSensorDataBySensor(Sensor sensor, Date currentTime, Random random) {
        SensorData sensorData = new SensorData();
        sensorData.setSensorId(sensor.getId());
        sensorData.setTime(currentTime);
        
        // 根据传感器名称和单位生成相应范围的假数据
        String sensorName = sensor.getSensorName();
        String unit = sensor.getUnit();
        
        if (sensorName != null) {
            double data = 0.0;
            
            if (sensorName.contains("风压") && ("Pa".equals(unit) || "pa".equals(unit))) {
                // 主通风机风压 (1500-2500 Pa) - 整数
                data = 1500 + random.nextInt(1001); // 1500 + [0-1000]
            } else if (sensorName.contains("电耗") && ("kW".equals(unit) || "kWh/m³".equals(unit))) {
                // 风机电耗 (20-40 kW) - 整数
                data = 20 + random.nextInt(21); // 20 + [0-20]
            } else if (sensorName.contains("流量") && ("L/min".equals(unit) || "m³/h".equals(unit))) {
                // 水泵流量 (20-40 L/min 或 m³/h) - 整数
                data = 20 + random.nextInt(21); // 20 + [0-20]
            } else if (sensorName.contains("风速") && "m/s".equals(unit)) {
                // 巷道风速 (0.2-0.7 m/s) - 一位小数
                double baseValue = 0.2 + random.nextDouble() * 0.5; // 0.2-0.7
                data = Math.round(baseValue * 10.0) / 10.0; // 保留一位小数
            } else {
                // 其他类型的传感器，生成通用范围的整数数据 (0-100)
                data = random.nextInt(101); // 0-100的整数
            }
            
            sensorData.setData(data);
            return sensorData;
        }
        
        return null; // 无法识别的传感器类型
    }

    /**
     * 批量新增传感器数据
     * 
     * @param sensorDataList 传感器数据集合
     * @return 结果
     */
    @Override
    public int insertSensorDataBatch(List<SensorData> sensorDataList)
    {
        int result = 0;
        for (SensorData sensorData : sensorDataList)
        {
            result += insertSensorData(sensorData);
        }
        return result;
    }

    /**
     * 获取固定设备的传感器数据
     * 
     * @param deviceId 设备ID
     * @param sensorId 传感器ID
     * @return 传感器数据VO集合
     */
    @Override
    public List<SensorDataVO> getFixedSensorData(Long deviceId, Long sensorId)
    {
        return sensorDataMapper.selectFixedSensorData(deviceId, sensorId);
    }

    /**
     * 获取固定设备的最新传感器数据
     * 
     * @param deviceId 设备ID
     * @param sensorId 传感器ID
     * @return 最新的传感器数据VO
     */
    @Override
    public SensorDataVO getLatestFixedSensorData(Long deviceId, Long sensorId)
    {
        return sensorDataMapper.selectLatestFixedSensorData(deviceId, sensorId);
    }

    /**
     * 获取固定设备的最新传感器数据值
     * 
     * @param deviceId 设备ID
     * @param sensorId 传感器ID
     * @return 最新的传感器数据值
     */
    @Override
    public Double getLatestFixedSensorDataValue(Long deviceId, Long sensorId)
    {
        return sensorDataMapper.selectLatestFixedSensorDataValue(deviceId, sensorId);
    }

    /**
     * 获取固定水泵设备的最新传感器数据值
     * 
     * @param areaId 区域ID
     * @param deviceId 设备ID
     * @param sensorId 传感器ID
     * @return 最新的水泵传感器数据值
     */
    @Override
    public Double getLatestWaterSensorDataValue(Long areaId, Long deviceId, Long sensorId)
    {
        return sensorDataMapper.selectLatestWaterSensorDataValue(areaId, deviceId, sensorId);
    }

    /**
     * 获取ABC三个区域的水泵流量数据
     * 查询条件：区域名称包含A、B、C，设备名称为'水泵'，传感器名称为'水泵流量'且状态为1
     * 
     * @return 水泵流量数据，包含设备名称列表和对应的数据值列表
     */
    @Override
    public WaterPumpDataVO getWaterPumpFlowDataFromABCAreas()
    {
        List<SensorDataVO> sensorDataList = sensorDataMapper.selectWaterPumpFlowDataFromABCAreas();
        
        List<String> equipments = new ArrayList<>();
        List<Double> dataValues = new ArrayList<>();
        
        for (SensorDataVO sensorDataVO : sensorDataList)
        {
            equipments.add(sensorDataVO.getDeviceName());
            dataValues.add(sensorDataVO.getData());
        }
        
        return new WaterPumpDataVO(equipments, dataValues);
    }

    /**
     * 获取指定矿山的固定传感器当日统计数据
     * 包括：风机的主通风机风压和风机电耗、风速测量仪的巷道风速、水泵的水泵流量
     * 
     * @param mineId 矿山ID
     * @return 指定矿山的固定传感器当日统计数据列表
     */
    @Override
    public List<AreaSensorDataVO> getMineAreaSensorDailyData(Long mineId)
    {
        return sensorDataMapper.selectMineAreaSensorDailyData(mineId);
    }
    
    /**
     * 获取指定矿山7天的风机电耗数据
     * 
     * @param mineId 矿山ID
     * @return 7天的风机电耗数据列表，包含日期和电耗值
     */
    @Override
    public List<java.util.Map<String, Object>> getMineSevenDayWindTurbineElectricData(Long mineId)
    {
        return sensorDataMapper.selectMineSevenDayWindTurbineElectricData(mineId);
    }

    /**
     * 获取指定矿山7天的风机电耗和产量数据
     * 
     * @param mineId 矿山ID
     * @return 包含电量、产量和日期数据的BatteryDataVO
     */
    @Override
    public BatteryDataVO getMineSevenDayBatteryData(Long mineId)
    {
        try {
            // 获取7天的风机电耗数据
            List<Map<String, Object>> electricData = sensorDataMapper.selectMineSevenDayWindTurbineElectricData(mineId);
            
            // 获取7天的产量数据
            List<Float> yieldData = miningRecordService.getMiningRecordSevenDaySum(mineId);
            
            // 准备返回数据的列表
            List<Integer> electricList = new ArrayList<>();
            List<Double> dayList = new ArrayList<>();
            List<Integer> yieldList = new ArrayList<>();
            
            // 处理电量数据和日期
            for (Map<String, Object> data : electricData) {
                // 处理电量数据，转换为整数
                Object electricValue = data.get("electric_value");
                if (electricValue != null) {
                    electricList.add(Double.valueOf(electricValue.toString()).intValue());
                } else {
                    electricList.add(0);
                }
                
                // 处理日期数据，格式为数字 (例如: 6.5)
                Object dateValue = data.get("date");
                if (dateValue != null) {
                    LocalDate date = LocalDate.parse(dateValue.toString());
                    double dayValue = Double.parseDouble(date.getMonthValue() + "." + date.getDayOfMonth());
                    dayList.add(dayValue);
                } else {
                    dayList.add(0.0);
                }
            }
            
            // 处理产量数据，确保和电量数据长度一致
            if (yieldData != null && !yieldData.isEmpty()) {
                // 转换Float到Integer并添加到结果列表
                for (Float yieldValue : yieldData) {
                    yieldList.add(yieldValue != null ? yieldValue.intValue() : 0);
                }
                
                // 如果产量数据长度不够，用0补充
                while (yieldList.size() < electricList.size()) {
                    yieldList.add(0);
                }
                // 如果产量数据过长，截取到合适长度
                if (yieldList.size() > electricList.size()) {
                    yieldList = yieldList.subList(0, electricList.size());
                }
            } else {
                // 如果没有产量数据，用0填充
                for (int i = 0; i < electricList.size(); i++) {
                    yieldList.add(0);
                }
            }
            
            return new BatteryDataVO(yieldList, dayList, electricList);
            
        } catch (Exception e) {
            e.printStackTrace();
            // 发生异常时返回空数据
            return new BatteryDataVO(new ArrayList<>(), new ArrayList<>(), new ArrayList<>());
        }
    }
}
